package com.lyq.interaction.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lyq.interaction.constant.ConnectionMap;
import com.lyq.interaction.mapper.MessageMapper;
import com.lyq.interaction.mapper.SessionMessageMapper;
import com.lyq.interaction.model.*;
import com.lyq.interaction.utils.JWTUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.Resource;
import java.util.List;

@Component
@Slf4j
public class WebSocketController extends TextWebSocketHandler {
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private SessionMessageMapper sessionMessageMapper;
    @Resource
    private MessageMapper messageMapper;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("连接成功");
        int userId = getUserIdBySession(session);
        ConnectionMap.onLine(userId, session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        log.info("收到消息 message: {}", message);
        //获取用户发送的消息
        WebSocketRequest webSocketRequest = objectMapper.readValue(message.getPayload(), WebSocketRequest.class);
        //获取发送者
        User user = new User();
        user.setUserId(getUserIdBySession(session));
        user.setUserName(getUserNameBySession(session));
        //构造一个转发的消息
        WebSocketResp resp = new WebSocketResp();
        resp.setType(webSocketRequest.getType());
        resp.setSessionId(webSocketRequest.getSessionId());
        resp.setUserId(user.getUserId());
        resp.setUserName(user.getUserName());
        resp.setContent(webSocketRequest.getContent());
        String ret = objectMapper.writeValueAsString(resp);
        //获取当前发送会话的所有好友id和name
        List<User> list = sessionMessageMapper.getSessionBySessionId(webSocketRequest.getSessionId(), user.getUserId());
        list.add(user);
        //给所有人转发该条消息
        for (User tmp : list) {
            WebSocketSession socketSession = ConnectionMap.getWSSessionById(tmp.getUserId());
            if (socketSession != null) {
                socketSession.sendMessage(new TextMessage(ret));
            }
        }
        //将该条消息存储在数据库中
        Integer a = messageMapper.sendMessage(user.getUserId(), webSocketRequest.getSessionId(), webSocketRequest.getContent(), webSocketRequest.getType());
        if (a != 1) {
            throw new RuntimeException("消息存储异常");
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.error("连接异常 exception: {}", exception.toString());
        int userId = getUserIdBySession(session);
        ConnectionMap.offLine(userId);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        log.info("连接关闭");
        int userId = getUserIdBySession(session);
        ConnectionMap.offLine(userId);
    }

    public Integer getUserIdBySession(WebSocketSession session) {
        String token = (String) session.getAttributes().get("userToken");
        Claims claims = JWTUtil.checkToken(token);
        return (Integer) claims.get("userId");
    }

    public String getUserNameBySession(WebSocketSession session) {
        String userToken = (String) session.getAttributes().get("userToken");
        Claims claims = JWTUtil.checkToken(userToken);
        return (String) claims.get("userName");
    }
}
